package com.zh.mycommon.viewdata;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.zh.mycommon.util.MyCommonUtil.collectSubtract;

/**
 * 一个对象的转换工具类
 * 用于各种数据包装对象的转换
 * 或者
 * 对集合的常用操作的封装
 */
public final class ToWrapper {

    /**
     * 如果入参不为null，则set值
     */
    public static <T> Consumer<T> set(Consumer<T> consumer) {
        return (e) -> {
            if (e != null)
                consumer.accept(e);
        };
    }

    /**
     * 如果入参string不为空，则set值
     */
    public static Consumer<String> setString(Consumer<String> consumer) {
        return (e) -> {
            if (StringUtils.isNotBlank(e))
                consumer.accept(e.trim());
        };
    }

    /**
     * 对对象进行操作，返回对象本身
     * @param t
     * @param fun
     * @return this
     * @param <T>
     */
    public static <T> T apply(T t, Consumer<T> fun){
        fun.accept(t);
        return t;
    }

    public static <V, T> V[] foreach(T[] arr, Function<T, V> convert) {
        Objects.requireNonNull(convert, "convert function 不能缺失");
        if (arr.length == 0) {
            @SuppressWarnings("unchecked")
            V[] empty = ArrayUtils.<V>toArray();
            return empty;
        }

        List<V> list = Arrays.stream(arr).map(convert).toList();
        @SuppressWarnings("unchecked")
        V[] shape = (V[]) java.lang.reflect.Array.newInstance(list.get(0).getClass(), arr.length);
        return list.toArray(shape);
    }

    public static <V, T> List<V> foreach(List<T> list, Function<T, V> convert) {
        Objects.requireNonNull(convert, "convert function 不能缺失");
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }
        return list.stream().map(convert).collect(Collectors.toList());
    }

    public static <V, T> Set<V> foreach(Set<T> set, Function<T, V> convert) {
        Objects.requireNonNull(convert, "convert function 不能缺失");
        if (set == null || set.isEmpty()) {
            return Collections.emptySet();
        }
        return set.stream().map(convert).collect(Collectors.toSet());
    }

    /**
     * 将两层list压扁为一层list
     *
     * @param collection 集合
     * @param <T>        T
     * @return list
     */
    public static <T> List<T> flatMap(Collection<List<T>> collection) {
        if (collection == null || collection.isEmpty()) {
            return Collections.emptyList();
        }
        return collection.stream().flatMap(Collection::stream).collect(Collectors.toList());
    }

    /**
     * 用户增删记录
     *
     * @param ownIds  旧的
     * @param funDel  删除方法
     * @param willIds 新的
     * @param funAdd  添加方法
     */
    public static <T> void operate(Set<T> ownIds, Consumer<Set<T>> funDel, Set<T> willIds, Consumer<Set<T>> funAdd) {
        if (ownIds == null) {
            ownIds = Collections.emptySet();
        }
        if (willIds == null) {
            willIds = Collections.emptySet();
        }

        if (!ownIds.isEmpty()) {
            Objects.requireNonNull(funDel, "funDel不能为null");
        }
        if (!willIds.isEmpty()) {
            Objects.requireNonNull(funAdd, "funAdd不能为null");
        }

        Set<T> willAddIds = collectSubtract(willIds, ownIds);
        Set<T> willDelIds = collectSubtract(ownIds, willIds);

        if (!willDelIds.isEmpty()) {
            funDel.accept(willDelIds);
        }

        if (!willAddIds.isEmpty()) {
            funAdd.accept(willAddIds);
        }
    }

    /**
     * PageData ——>  PageData
     */
    public static <V, T> PageData<V> asPageData(PageData<T> pageData, Function<T, V> convert) {
        return PageData.of(pageData.getNum(), pageData.getSize(), pageData.getTotal(), foreach(pageData.getList(), convert));
    }

}
